use std::result;

fn largest<T: PartialOrd/*trait bound */>(list: &[T] ) -> &T {
    let mut largest = &list[0];

    for item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }

    fn y(&self) -> &T {
        &self.y
    }
}

impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

// trait
pub trait Summary {
    fn summarize(&self) -> String;
}

struct NewsArticle {
    headline: String,
    author: String,
    content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.content)
    }
}

fn notify(item: &impl Summary) {
    println!("Breaking news! {}", item.summarize());
}

fn longest_str<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() {
        s1
    } else {
        s2
    }
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&number_list);
    println!("The largest number is {result}");

    let char_list = vec!['y', 'm', 'a', 'q'];

    let result = largest(&char_list);
    println!("The largest char is {result}");

    let float_list = vec![3.4, 6.7, 1.2, 8.9];

    let result = largest(&float_list);
    println!("The largest float is {result}");

    let point1 = Point { x: 1.1, y: 2.2 };
    let point2 = Point { x: 5, y: 6 };
    println!("x: {}, y: {}",point1.x(),point1.y());
    println!("x: {}, y: {}",point2.x(),point2.y());
    println!("Distance from origin: {}",point1.distance_from_origin());

    let article = NewsArticle {
        headline: String::from("Penguins win the Stanley Cup Championship"),
        author: String::from("The New York Times"),
        content: String::from("The Penguins defeated the Sharks 4-0 in the Stanley Cup on Saturday, giving them the Championship title."),
    };

    println!("{}",article.summarize());
    notify(&article);

    let string1 = String::from("long string is long");
    {
        let string2 = String::from("xyz");
        let result = longest_str(string1.as_str(), string2.as_str());
        println!("The longest string is {result}");
    }
}